package com.qd.tc.service.impl;

import java.util.*;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.qd.string.StringExUtils;
import com.qd.tc.service.AbstractTCDataConvertService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.Document;
import org.springframework.beans.factory.InitializingBean;

import com.qd.date.DateExUtils;
import com.qd.dom.XmlUtils;
import com.qd.base.ResHeader;
import com.qd.dom.XmlUtils;
import com.qd.http.service.HttpAccessService;
import com.qd.tc.model.*;
import com.qd.tc.service.TcSceneryService;
import com.qd.util.AccessMethod;

import com.qd.util.ReflectUtils;
import lombok.Setter;
import org.dom4j.Document;
import org.dom4j.Element;

/**
 * @author taomk
 * @version 1.0
 * @since 2014/10/12 23:09
 */
@Slf4j
public class TcSceneryServiceImpl extends AbstractTCDataConvertService implements TcSceneryService, InitializingBean {

	@Setter
	private HttpAccessService httpAccessService;

	@Setter
	private String themeXmlPath;

	private List<TcSceneryTheme> themeList;

	@Override
	public TcSceneryResEntity find(TcSceneryParam param) {
        log.info("调用TC_SCENERY_LIST接口，访问参数为：" + param);
		String res = httpAccessService.access(AccessMethod.TC_SCENERY_LIST, param.toMap());
        log.info("调用TC_SCENERY_LIST接口，返回结果为：" + res);
        TcSceneryResEntity tcSceneryResEntity = new TcSceneryResEntity();
		//res转TcSceneryRes集合
        List<TcSceneryRes> resultList = new ArrayList();
        Document doc = XmlUtils.parseStringToXml(res);
        Element root =  doc.getRootElement();
        //解析header
        ResHeader resHeader = new ResHeader();
        List<Element> headerChildEleList =  root.element("header").elements();
        reflectResultToObj(headerChildEleList, resHeader);
        tcSceneryResEntity.setHeader(resHeader);
        //解析body
        if(StringExUtils.isNotNullOrEmpty(resHeader.getRspType()) && resHeader.getRspType().equals("0") && "0000".equals(resHeader.getRspCode())){
            Element sceneryList = root.element("body").element("sceneryList");
            tcSceneryResEntity.setPage(sceneryList.attributeValue("page"));
            tcSceneryResEntity.setPageSize(sceneryList.attributeValue("pageSize"));
            tcSceneryResEntity.setTotalPage(sceneryList.attributeValue("totalPage"));
            tcSceneryResEntity.setTotalCount(sceneryList.attributeValue("totalCount"));
            tcSceneryResEntity.setImgbaseURL(sceneryList.attributeValue("imgbaseURL"));
            List<Element> sceneryListChildEleList =  sceneryList.elements();//获取scenery元素列表
            for(Element element : sceneryListChildEleList){
                List<Element> sceneryChildEleList = element.elements();
                TcSceneryRes tcSceneryRes = new TcSceneryRes();
                reflectResultToObj(sceneryChildEleList, tcSceneryRes);
                resultList.add(tcSceneryRes);
            }
            tcSceneryResEntity.setTcSceneryResList(resultList);
        }
        log.info("TcSceneryServiceImpl.find返回结果为：" + tcSceneryResEntity);
		return tcSceneryResEntity;
	}

	@Override
	public TcSceneryDetailRes findById(String sceneryId) {
		Map<String, String> param = new HashMap<>();
		param.put("sceneryId", String.valueOf(sceneryId));
		param.put("cs", "2");
        log.info("调用TC_SCENERY_DETAIL接口，访问参数为：" + param);
		String res = httpAccessService.access(AccessMethod.TC_SCENERY_DETAIL, param);
        log.info("调用TC_SCENERY_DETAIL接口，返回结果为：" + res);
		//res转TcSceneryDetailRes
        TcSceneryDetailRes tcSceneryDetailRes = new TcSceneryDetailRes();
        Document doc = XmlUtils.parseStringToXml(res);
        Element root =  doc.getRootElement();
        //解析header
        ResHeader resHeader = new ResHeader();
        List<Element> headerList =  root.element("header").elements();
        reflectResultToObj(headerList, resHeader);
        tcSceneryDetailRes.setHeader(resHeader);
        //解析body
        if(StringExUtils.isNotNullOrEmpty(resHeader.getRspType()) && resHeader.getRspType().equals("0") && "0000".equals(resHeader.getRspCode())){
            List<Element> bodyList =  root.element("body").element("scenery").elements();
            reflectResultToObj(bodyList, tcSceneryDetailRes);
        }
        log.info("TcSceneryServiceImpl.findById返回结果为：" + tcSceneryDetailRes);
        return tcSceneryDetailRes;
	}

	@Override
	public List<TcSceneryTheme> findThemes() {
		return themeList;
	}

	@Override
	public List<TcSceneryPriceRes> findPriceById(String... sceneryIds) {
        List<TcSceneryPriceRes> result = new ArrayList<>();

        StringBuilder sceneryIdParam = new StringBuilder();
        int count = 1;
        for (String sceneryId : sceneryIds) {
            if (count % 20 == 0) {
                result.addAll(findSceneryPriceById(sceneryIdParam.toString()));
                sceneryIdParam = new StringBuilder();
            }
            sceneryIdParam.append(sceneryId).append(",");
            count++;
        }

        if (StringUtils.isNotBlank(sceneryIdParam.toString())) {
            result.addAll(findSceneryPriceById(sceneryIdParam.toString()));
        }

        return result;
    }

    @Override
    public List<TcSceneryPriceRes> findPriceByIdList(List<String> sceneryIdList) {
        List<TcSceneryPriceRes> result = new ArrayList<>();
        StringBuilder sceneryIdParam = new StringBuilder();
        int count = 1;
        for (String sceneryId : sceneryIdList) {
            if (count % 20 == 0) {
                result.addAll(findSceneryPriceById(sceneryIdParam.toString()));
                sceneryIdParam = new StringBuilder();
            }
            sceneryIdParam.append(sceneryId).append(",");
            count++;
        }

        if (StringUtils.isNotBlank(sceneryIdParam.toString())) {
            result.addAll(findSceneryPriceById(sceneryIdParam.toString()));
        }

        return result;
    }

	private List<TcSceneryPriceRes> findSceneryPriceById(String sceneryIds) {
		Map<String, String> param = new HashMap<>();
		param.put("showDetail", "1");
		param.put("sceneryIds", sceneryIds);
		param.put("payType", "0");
		param.put("useCache", "0");
        log.info("调用TC_SCENERY_PRICE接口，访问参数为：" + param);
		String res = httpAccessService.access(AccessMethod.TC_SCENERY_PRICE, param);
        log.info("调用TC_SCENERY_PRICE接口，返回结果为：" + res);
		//res转TcSceneryPriceRes集合
        List<TcSceneryPriceRes> resultList = new ArrayList();
        Document doc = XmlUtils.parseStringToXml(res);
        Element root =  doc.getRootElement();
        //解析header
        ResHeader resHeader = new ResHeader();
        List<Element> headerList =  root.element("header").elements();
        reflectResultToObj(headerList, resHeader);
        //解析body（需要解析sceneryId，policys，notices，ahead）
        if(StringExUtils.isNotNullOrEmpty(resHeader.getRspType()) && resHeader.getRspType().equals("0") && "0000".equals(resHeader.getRspCode())){
            List<Element> sceneryListChildEleList =  root.element("body").element("sceneryList").elements();//获取scenery元素列表
            for(Element element : sceneryListChildEleList){
                List<Element> sceneryChildEleList = element.elements();
                TcSceneryPriceRes tcSceneryPriceRes = new TcSceneryPriceRes();
                //解析sceneryId
                tcSceneryPriceRes.setSceneryId(element.element("sceneryId").getStringValue());
                //解析价格;
                List<Element> policyChildEleList = element.element("policy").elements(); //标签<p>的列表
                List<TcSceneryPolicy> policys = new ArrayList();
                for(Element pElement : policyChildEleList){
                    List<Element> ele = pElement.elements();
                    TcSceneryPolicy tcSceneryPolicy = new TcSceneryPolicy();
                    reflectResultToObj(ele, tcSceneryPolicy);
                    policys.add(tcSceneryPolicy);
                }
                tcSceneryPriceRes.setPolicys(policys);
                //解析notice
                List<Element> noticeChildEleList = element.element("notice").elements(); //标签<p>的列表
                List<TcSceneryNotice> notices = new ArrayList();
                for(Element nElement : noticeChildEleList){
                    List<Element> nChildEleList = nElement.elements();
                    TcSceneryNotice tcSceneryNotice = new TcSceneryNotice();
                    reflectResultToObj(nChildEleList, tcSceneryNotice);
                    //解析TcSceneryNotice内的infos
                    List<Element> nInfoChildEleList =  nElement.element("nInfo").elements();
                    for(Element infoElement : nInfoChildEleList){
                        TcSceneryNoticeInfo tcSceneryNoticeInfo = new TcSceneryNoticeInfo();
                        if(tcSceneryNotice.getInfos() == null){
                            tcSceneryNotice.setInfos(new ArrayList());
                        }
                        reflectResultToObj(infoElement.elements(), tcSceneryNoticeInfo);
                        tcSceneryNotice.getInfos().add(tcSceneryNoticeInfo);
                    }
                    notices.add(tcSceneryNotice);
                }
                //解析TcSceneryAhead
                TcSceneryAhead tcSceneryAhead = new TcSceneryAhead();
                List<Element> aheadChildEleList = element.element("ahead").elements();
                reflectResultToObj(aheadChildEleList, tcSceneryAhead);
                //组装
                System.out.println("policys.size() = " + policys.size() + "\n" + policys);
                tcSceneryPriceRes.setPolicys(policys);
                System.out.println("notices.size() = " + notices.size() + "\n" + notices);
                tcSceneryPriceRes.setNotices(notices);
                tcSceneryPriceRes.setAhead(tcSceneryAhead);
                resultList.add(tcSceneryPriceRes);
            }
        }
        log.info("TcSceneryServiceImpl.findSceneryPriceById返回结果为：" + resultList);
        return resultList;
	}

	@Override
	public TcSceneryPriceCalendarRes findPriceCalendarById(String policyId) {
		Map<String, String> param = new HashMap<>();
		param.put("policyId", policyId);
		param.put("startDate", DateExUtils.currentDate());
		param.put("endDate", StringUtils.EMPTY);
		param.put("showDetail", "0");
        log.info("调用TC_SCENERY_PRICE_CALENDAR接口，访问参数为：" + param);
		String res = httpAccessService.access(AccessMethod.TC_SCENERY_PRICE_CALENDAR, param);
        log.info("调用TC_SCENERY_PRICE_CALENDAR接口，返回结果为：" + res);
		//res转TcSceneryPriceCalendarRes集合
        TcSceneryPriceCalendarRes tcSceneryPriceCalendarRes = new TcSceneryPriceCalendarRes();
        Document doc = XmlUtils.parseStringToXml(res);
        Element root =  doc.getRootElement();
        //解析header
        ResHeader resHeader = new ResHeader();
        List<Element> headerList =  root.element("header").elements();
        reflectResultToObj(headerList, resHeader);
        //解析body
        if(StringExUtils.isNotNullOrEmpty(resHeader.getRspType()) && resHeader.getRspType().equals("0") && "0000".equals(resHeader.getRspCode())){
            Element calendarInfoElement = root.element("body").element("calendarInfo");
            List<Element> calendarInfoChildEleList = calendarInfoElement.elements();//<calendarInfo>子标签列表
            Set<String> excludeFields = new HashSet();
            excludeFields.add("ahead");
            excludeFields.add("calendar");
            reflectResultToObj(calendarInfoChildEleList, tcSceneryPriceCalendarRes, excludeFields);
            //解析notices
            List<Element> noticeChildEleList = calendarInfoElement.element("notice").elements(); //标签<n>的列表
            List<TcSceneryNotice> notices = new ArrayList();
            for(Element nElement : noticeChildEleList){
                List<Element> nChildEleList = nElement.elements();
                TcSceneryNotice tcSceneryNotice = new TcSceneryNotice();
                reflectResultToObj(nChildEleList, tcSceneryNotice);
                //解析TcSceneryNotice内的infos
                List<Element> nInfoChildEleList =  nElement.element("nInfo").elements();
                for(Element infoElement : nInfoChildEleList){
                    TcSceneryNoticeInfo tcSceneryNoticeInfo = new TcSceneryNoticeInfo();
                    if(tcSceneryNotice.getInfos() == null){
                        tcSceneryNotice.setInfos(new ArrayList());
                    }
                    reflectResultToObj(infoElement.elements(), tcSceneryNoticeInfo);
                    tcSceneryNotice.getInfos().add(tcSceneryNoticeInfo);
                }
                notices.add(tcSceneryNotice);
            }
            //解析calendars
            List<Element> calendarChildEleList = calendarInfoElement.element("calendar").elements(); //标签<day>的列表
            List<TcSceneryPriceCalendar> calendars = new ArrayList();
            for(Element dayElement : calendarChildEleList){
                List<Element> dayChildEleList = dayElement.elements();
                TcSceneryPriceCalendar tcSceneryPriceCalendar = new TcSceneryPriceCalendar();
                reflectResultToObj(dayChildEleList, tcSceneryPriceCalendar);
                calendars.add(tcSceneryPriceCalendar);
            }
            //解析ahead
            TcSceneryAhead tcSceneryAhead = new TcSceneryAhead();
            List<Element> aheadChildEleList = calendarInfoElement.element("ahead").elements();
            reflectResultToObj(aheadChildEleList, tcSceneryAhead);
            //组装
            tcSceneryPriceCalendarRes.setHeader(resHeader);
            tcSceneryPriceCalendarRes.setNotices(notices);
            tcSceneryPriceCalendarRes.setCalendars(calendars);
            System.out.println(tcSceneryAhead);
            tcSceneryPriceCalendarRes.setAhead(tcSceneryAhead);
        }
        log.info("TcSceneryServiceImpl.findPriceCalendarById返回结果为：" + tcSceneryPriceCalendarRes);
        return tcSceneryPriceCalendarRes;
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		themeList = new ArrayList<>();
		if (StringUtils.isNotBlank(themeXmlPath)) {
			Document reqParamDoc = XmlUtils.parseFIOToXml(themeXmlPath);
			//reqParamDoc转themeList
            if(reqParamDoc!=null){
                Element rootEle = reqParamDoc.getRootElement();
                List<Element> themsEleList = rootEle.elements();
                for(Element element : themsEleList){
                    TcSceneryTheme tcSceneryTheme = new TcSceneryTheme();
                    tcSceneryTheme.setThemeId(element.element("id").getStringValue());
                    tcSceneryTheme.setThemeName(element.element("name").getStringValue());
                    themeList.add(tcSceneryTheme);
                }
                log.info("TcSceneryServiceImpl.afterPropertiesSet执行完毕，themeList结果为：" + themeList);
            }
		}
	}

    @Override
    public TcSceneryImageRes findImageById(String sceneryId, int page, int pageSize) {
        Map<String, String> param = Maps.newHashMap();
        param.put("sceneryId", sceneryId);
        param.put("page", String.valueOf(page));
        param.put("pageSize", String.valueOf(pageSize));
        log.info("调用TC_SCENERY_IMAGE_LIST接口，访问参数为：" + param);
        String res = httpAccessService.access(AccessMethod.TC_SCENERY_IMAGE_LIST, param);
        log.info("调用TC_SCENERY_IMAGE_LIST接口，返回结果为：" + res);
        //res转TcSceneryImageRes
        TcSceneryImageRes tcSceneryImageRes = new TcSceneryImageRes();
        Document doc = XmlUtils.parseStringToXml(res);
        Element root =  doc.getRootElement();
        //解析header
        ResHeader resHeader = new ResHeader();
        List<Element> headerList =  root.element("header").elements();
        reflectResultToObj(headerList, resHeader);
        //解析body
        if(StringExUtils.isNotNullOrEmpty(resHeader.getRspType()) && resHeader.getRspType().equals("0") && "0000".equals(resHeader.getRspCode())){
            Element imageListElement = root.element("body").element("imageList");
            tcSceneryImageRes.setPage(imageListElement.attributeValue("page"));
            tcSceneryImageRes.setPageSize(imageListElement.attributeValue("pageSize"));
            tcSceneryImageRes.setTotalPage(imageListElement.attributeValue("totalPage"));
            tcSceneryImageRes.setTotalCount(imageListElement.attributeValue("totalCount"));
            List<Element> imageElementList = imageListElement.elements();
            //解析imageList
            List<TcSceneryImage> tcSceneryImageList = Lists.newArrayList();
            for(Element element : imageElementList){
                TcSceneryImage tcSceneryImage = new TcSceneryImage();
                reflectResultToObj(element.elements(), tcSceneryImage);
                tcSceneryImageList.add(tcSceneryImage);
            }
            //解析extInfoOfImageList
            TcSceneryImageExtInfo tcSceneryImageExtInfo = null;
            if(tcSceneryImageList.size() != 0){
                Element imageExtInfoElement =  root.element("body").element("extInfoOfImageList");
                tcSceneryImageExtInfo = new TcSceneryImageExtInfo();
                tcSceneryImageExtInfo.setImageBaseUrl(imageExtInfoElement.elementText("imageBaseUrl"));
                List<Element> sizeCodeEleList = imageExtInfoElement.element("sizeCodeList").elements();
                List<TcSceneryImageSizeCode> sizeCodeList = Lists.newArrayList();
                for (Element element : sizeCodeEleList) {
                    TcSceneryImageSizeCode sizeCode = new TcSceneryImageSizeCode();
                    sizeCode.setSize(element.attributeValue("size"));
                    sizeCode.setIsDefault(element.attributeValue("isDefault"));
                    sizeCode.setSizeCode(element.getText());
                    sizeCodeList.add(sizeCode);
                }
                tcSceneryImageExtInfo.setSizeCodeList(sizeCodeList);
            }
            //组装
            tcSceneryImageRes.setTcSceneryImageList(tcSceneryImageList);
            tcSceneryImageRes.setTcSceneryImageExtInfo(tcSceneryImageExtInfo);
        }
        tcSceneryImageRes.setHeader(resHeader);
        log.info("TcSceneryServiceImpl.findImageById返回结果为：" + tcSceneryImageRes);
        return tcSceneryImageRes;
    }
}
